package com.hyx.api.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyx.api.domain.*;
import com.hyx.api.domain.bo.CompanyBo;
import com.hyx.api.domain.bo.MsgDialogueOrderBo;
import com.hyx.api.domain.bo.ShopRecOrderQueBo;
import com.hyx.api.domain.bo.UserBo;
import com.hyx.api.domain.bo.WithdrawReqBo;
import com.hyx.api.domain.vo.ShopOrderListVo;
import com.hyx.api.enums.RecycleOrderStatusEnum;
import com.hyx.api.enums.SpreadStatusEnum;
import com.hyx.api.enums.UserTypeEnum;
import com.hyx.api.enums.YesNoEnum;
import com.hyx.api.mapper.*;
import com.hyx.api.service.IAppCommonService;
import com.hyx.api.service.pc_admin.IWalletService;
import com.hyx.api.utils.MD5Util;
import com.hyx.api.utils.base.MobileBaseService;
import com.ruoyi.common.alipay.AlipayApi;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.wx.WxApi;
import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class IAppCommonServiceImpl implements IAppCommonService {

    private static final Logger log = LoggerFactory.getLogger(IAppCommonServiceImpl.class);

    private final UserMapper userMapper;

    private final CompanyMapper companyMapper;

    private final MsgDialogueOrderMapper msgDialogueMapper;

    private final InquiryOrderMapper inquiryOrderMapper;

    private final FileUploadMapper uploadMapper;

    private final VerifyModelOptionMapper verifyModelOptionMapper;

    private final OfferOrderMapper offerOrderMapper;

    private final RecycleOrderMapper recycleOrderMapper;

    private final RefundOrderMapper refundOrderMapper;

    private final SpreadOrderMapper spreadOrderMapper;

    private final WalletMapper walletMapper;

    private final WalletChangeInfoMapper walletChangeInfoMapper;

    private final CustomerWithdrawMapper customerWithdrawMapper;

    private final MobileBaseService mobileBaseService;

    private final IWalletService walletService;

    private final CfgAreaMapper cfgAreaMapper;

    private final WithdrawThirdInfoMapper withdrawThirdInfoMapper;

    @Override
    public AjaxResult createUser(UserBo bo) {
        User currentUser = mobileBaseService.hasLogin();
        LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
        lqw.eq(User::getUsername, bo.getUsername());
        lqw.eq(User::getDelFlag, 0);
        lqw.ne(ObjectUtils.isNotEmpty(bo.getId()), User::getId, bo.getId());
        Long count = userMapper.selectCount(lqw);
        if (count > 0) {
            return AjaxResult.error("该账号已存在");
        }
        User user = new User();
        BeanUtils.copyProperties(bo, user);
        user.setCreateId(currentUser.getId());
        user.setCompanyId(currentUser.getCompanyId());
        user.setRecoveryId(currentUser.getRecoveryId());
        if (user.getType() == 3) {
            user.setStoreId(currentUser.getStoreId());
        }
        int num = 0;
        if (ObjectUtils.isNotEmpty(bo.getId())) {
            if (ObjectUtils.isNotEmpty(bo.getPassword()))
                user.setPassword(MD5Util.encrypt32(user.getPassword()));

            num = userMapper.updateById(user);
        } else {
            user.setPassword(MD5Util.encrypt32(user.getPassword()));
            num = userMapper.insert(user);
        }
        return num > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /*修改角色为店长*/
    public AjaxResult updateUserStore(Long id) {
        if (ObjectUtils.isEmpty(id))
            return AjaxResult.error();
        //获取用户信息
        User user = userMapper.selectById(id);
        if (ObjectUtils.isEmpty(user))
            throw new RuntimeException("没有找到用户信息");
        if (ObjectUtils.isEmpty(user.getStoreId()))
            throw new RuntimeException("该用户不属于任何门店");
        LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
        lqw.eq(User::getStoreId, user.getStoreId());
        lqw.eq(User::getType, UserTypeEnum.SHOP_OWNER.code()); //角色为店长
        User storeUser = userMapper.selectOne(lqw);
        if (ObjectUtils.isNotEmpty(storeUser)) {
            storeUser.setType(UserTypeEnum.SHOP_OPERATOR.code());
            userMapper.updateById(storeUser);
        }
        user.setType(UserTypeEnum.SHOP_OWNER.code());
        return userMapper.updateById(user) > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult sendOrderMsg(MsgDialogueOrderBo bo) {
        User user = mobileBaseService.hasLogin();
        MsgDialogueOrder insertDO = new MsgDialogueOrder();
        BeanUtils.copyProperties(bo, insertDO); //复制
        insertDO.setIsRead(0);
        insertDO.setSendUser(user.getId());

        msgDialogueMapper.insert(insertDO);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult readMsgOrder(List<Long> ids) {
        mobileBaseService.hasLogin();
        List<MsgDialogueOrder> updateDoS = new ArrayList<>();
        for (Long id : ids) {
            MsgDialogueOrder updateDO = new MsgDialogueOrder();
            updateDO.setId(id);
            updateDO.setIsRead(YesNoEnum.YES.code());
            updateDoS.add(updateDO);
        }
        return msgDialogueMapper.updateBatchById(updateDoS) ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    @Transactional
    public AjaxResult confirmPay(Long orderId) {
        User user = mobileBaseService.hasLogin();
        //目前只支持两种订单支付，回收订单和追差订单
        RecycleOrder recycleOrder;
        SpreadOrder spreadOrder = spreadOrderMapper.selectById(orderId);
        if (spreadOrder == null) {
            recycleOrder = recycleOrderMapper.selectById(orderId);
        } else {
            recycleOrder = recycleOrderMapper.selectById(spreadOrder.getRecycleOrderId());
        }
        if (recycleOrder == null) {
            return AjaxResult.error("支付失败");
        } else {
            if (!Objects.equals(user.getCompanyId(), recycleOrder.getCompanyId()) &&
                    !Objects.equals(user.getRecoveryId(), recycleOrder.getRecycleBusId())) {
                return AjaxResult.error("不能操作别人的数据");
            } else {
                return executePay(spreadOrder, recycleOrder, user);
            }
        }
    }

    @Transactional
    @Override
    public AjaxResult withdraw(WithdrawReqBo reqBo) {
        CustomerWithdraw withdraw = customerWithdrawMapper.selectById(reqBo.getId());
        if (withdraw == null) {
            log.error("客户提现错误，原因是没有该待提现订单，参数为:{}", JSON.toJSONString(reqBo));
            return AjaxResult.error("提现错误");
        } else {
            if (Objects.equals(withdraw.getStatus(), 1)) {
                return AjaxResult.error("已提现，不能重复提现，请稍后查看到账记录");
            }
        }
        withdraw.setStatus(1);  //已提现
        withdraw.setWithdrawChannel(reqBo.getType());
        //todo 提现相关代码
        WithdrawThirdInfo thirdInfo = new WithdrawThirdInfo();
        thirdInfo.setCustomerWithdrawId(withdraw.getId());
        thirdInfo.setWithdrawChannel(reqBo.getType());
        thirdInfo.setName(reqBo.getName());
        thirdInfo.setWithdrawAmount(withdraw.getPrice().longValue());
        if ("Alipay".equalsIgnoreCase(reqBo.getType())) {
            withdraw.setPhone(reqBo.getCode());
            Map<String, Object> transferMap = null;
            try {
                transferMap = AlipayApi.transferToPerson(reqBo.getCode(), reqBo.getName(), withdraw.getPrice());
            } catch (Exception e) {
                log.error("支付宝提现失败，失败原因：{}", e.getMessage());
                withdraw.setStatus(2);//提现失败
                customerWithdrawMapper.updateById(withdraw);
                return AjaxResult.error(e.getMessage());
            }
            //创建三方提现记录数据
            thirdInfo.setPhone(reqBo.getCode());
            thirdInfo.setOrderId(transferMap.get("orderId").toString());
            thirdInfo.setOutBizNo(transferMap.get("outBizNo").toString());
            thirdInfo.setPayFundOrderId(transferMap.get("payFundOrderId").toString());
            thirdInfo.setSettleSerialNo(transferMap.get("settleSerialNo").toString());
            thirdInfo.setTransDate(DateUtil.parseDateTime(transferMap.get("transDate").toString()));
            withdrawThirdInfoMapper.insert(thirdInfo);
        } else if ("Wechat".equalsIgnoreCase(reqBo.getType())) {
            String openId = WxApi.getWxUserOpenId(reqBo.getCode());
            if (openId == null) {
                log.error("微信提现失败，code->{}，获取openId失败", reqBo.getCode());
                return AjaxResult.error("提现失败，失败原因：获取用户微信openId失败");
            }
            InitiateBatchTransferResponse wxResponse;
            try {
                wxResponse = WxApi.transferToUser(openId, reqBo.getName(), withdraw.getPrice());
            } catch (Exception e) {
                log.error("微信提现失败，失败原因：{}", e.getMessage());
                withdraw.setStatus(2);//提现失败
                customerWithdrawMapper.updateById(withdraw);
                return AjaxResult.error(e.getMessage());
            }
            thirdInfo.setOpenId(openId);
            thirdInfo.setOutBizNo(wxResponse.getOutBatchNo());
            thirdInfo.setBatchId(wxResponse.getBatchId());
            thirdInfo.setBatchStatus(wxResponse.getBatchStatus());
            thirdInfo.setTransDate(new DateTime(wxResponse.getCreateTime()));
            withdrawThirdInfoMapper.insert(thirdInfo);
        } else {
            return AjaxResult.error("暂不支持此种提现方式");
        }
        customerWithdrawMapper.updateById(withdraw);
        return AjaxResult.success("提现成功，请稍后查看到账记录");
    }

    private AjaxResult executePay(SpreadOrder spreadOrder, RecycleOrder recycleOrder, User user) {
        BigDecimal amount;
        if (spreadOrder != null) {
            amount = spreadOrder.getSpread();
        } else {
            amount = recycleOrder.getPrice();
        }
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            return AjaxResult.error("金额错误");
        }
        int num = 0;
        InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(recycleOrder.getInquiryOrderId());
        OfferOrder offerOrder = offerOrderMapper.selectById(inquiryOrder.getOfferId());
        if (user.getCompanyId() != null) {
            LambdaQueryWrapper<Wallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(Wallet::getCompanyId, user.getCompanyId());
            Wallet companyWallet = walletMapper.selectOne(wrapper);
            if (companyWallet.getMoney().compareTo(amount) < 0) {
                return AjaxResult.error("余额不足");
            }

            wrapper.clear();
            wrapper.eq(Wallet::getRecoveryBusId, recycleOrder.getRecycleBusId());
            Wallet recycleWallet = walletMapper.selectOne(wrapper);

            //钱包表更新
            num += walletService.subMoney(amount, companyWallet.getId(), user.getNickName());//公司减少
            num += walletService.addMoney(amount, recycleWallet.getId(), user.getNickName());//回收商增加

        } else {
            //回收商支付给门店
            LambdaQueryWrapper<Wallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(Wallet::getRecoveryBusId, user.getRecoveryId());
            Wallet recycleWallet = walletMapper.selectOne(wrapper);
            if (recycleWallet.getMoney().compareTo(amount) < 0) {
                return AjaxResult.error("余额不足");
            }

            wrapper.clear();
            wrapper.eq(Wallet::getCompanyId, recycleOrder.getCompanyId());
            Wallet companyWallet = walletMapper.selectOne(wrapper);

            //钱包表更新
            num += walletService.addMoney(amount, companyWallet.getId(), user.getNickName()); //公司加钱
            num += walletService.subMoney(amount, recycleWallet.getId(), user.getNickName()); //回收商减少

            //新增提现记录
            CustomerWithdraw customerWithdrawDO = new CustomerWithdraw();
            customerWithdrawDO.setRecycleOrderId(recycleOrder.getId());
            //提现金额应该为总报价减去公司的利率金额
            if (offerOrder.getRateAmount() == null) {
                customerWithdrawDO.setPrice(offerOrder.getOfferPrice());
            } else {
                customerWithdrawDO.setPrice(offerOrder.getOfferPrice().subtract(offerOrder.getRateAmount()));
            }
            customerWithdrawDO.setStatus(0);//未提现
            customerWithdrawMapper.insert(customerWithdrawDO);
        }
        if (num > 0) {
            if (spreadOrder != null) {
                spreadOrder.setStatus(SpreadStatusEnum.SPREAD_FINISH.code());
                spreadOrderMapper.updateById(spreadOrder);
            } else {
                recycleOrder.setStatus(RecycleOrderStatusEnum.NO_SEND.code());
                recycleOrderMapper.updateById(recycleOrder);
            }
        }
        return num > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult createShop(CompanyBo bo) {
        User user = mobileBaseService.hasLogin();
        QueryWrapper<Company> wrapper = new QueryWrapper<>();
        wrapper.eq("name", bo.getName()).eq("parent_id", user.getCompanyId());
        Long count = companyMapper.selectCount(wrapper);
        if (count > 0) {
            return AjaxResult.error("该门店已存在");
        }
        Company companyDO = new Company();
        BeanUtils.copyProperties(bo, companyDO);
        companyDO.setParentId(user.getCompanyId());
        companyDO.setCreateBy(user.getUsername());
        // 门店
        companyDO.setType(2);
        companyDO.setUserId(user.getSysUserId());
        int num = 0;
        if (ObjectUtils.isNotEmpty(bo.getId())) {
            num = companyMapper.updateById(companyDO);
        } else {
            num = companyMapper.insert(companyDO);
        }
        return num > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 门店列表
     *
     * @return
     */
    @Override
    public AjaxResult queryStoreAndClerkList() {
        User user = mobileBaseService.hasLogin();
        LambdaQueryWrapper<Company> lqw = Wrappers.lambdaQuery();
        LambdaQueryWrapper<User> lqw2 = Wrappers.lambdaQuery();
        // 门店
        lqw.eq(Company::getType, 2);
        if (user.getType().equals(UserTypeEnum.COMPANY.code())) {
            lqw.eq(Company::getParentId, user.getCompanyId());
            lqw2.eq(User::getCompanyId, user.getCompanyId());
        } else {
            lqw.eq(Company::getId, user.getStoreId());
            lqw2.eq(User::getStoreId, user.getStoreId());
        }
        //门店列表
        List<Company> storeList = companyMapper.selectList(lqw);
        List<User> userList = userMapper.selectList(lqw2);
        for (Company c : storeList) {
            List<User> children = new ArrayList<>();
            for (User u : userList) {
                u.setPassword(null);
                if (Objects.equals(u.getStoreId(), c.getId()))
                    children.add(u);
            }
            c.setChildren(children);
        }
        return AjaxResult.success(storeList);
    }

    @Override
    public AjaxResult queryOfferList() {
        User user = mobileBaseService.hasLogin();
        LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
        lqw.eq(User::getType, 1); //报价师
        lqw.eq(User::getDelFlag, 0);
        lqw.eq(User::getRecoveryId, user.getRecoveryId());
        return AjaxResult.success(userMapper.selectList(lqw));
    }

    @Override
    public List<ShopOrderListVo> queryRecycleOrderList(ShopRecOrderQueBo req) {
        User user = mobileBaseService.hasLogin();
        List<ShopOrderListVo> orderListVos;
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(), user.getId(),
                    null, null, null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(), null,
                    null, null, null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), null, null,
                    user.getCompanyId(), null, null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.OFFER_OPERATOR.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), null, null,
                    req.getCompanyOrShopId() == null ? null : (long) req.getCompanyOrShopId(), user.getId(), null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SUM_ACCOUNT.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(req.getStatus(), user.getRecoveryId().intValue(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), null, null,
                    req.getCompanyOrShopId() == null ? null : (long) req.getCompanyOrShopId(), null, null);
        } else {
            return new ArrayList<>();
        }

        for (ShopOrderListVo orderListVo : orderListVos) {
            InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(orderListVo.getInquiryOrderId());
            List<VerifyModelOption> options = verifyModelOptionMapper.selectBatchIds(Arrays.asList(inquiryOrder.getVerifyModelIds().split(",")));
            orderListVo.setSpecs(options.stream().filter(s -> s.getType() == 1).map(VerifyModelOption::getName).collect(Collectors.joining(",")));
            List<FileUpload> files = uploadMapper.selectBatchIds(Arrays.asList(inquiryOrder.getFileIds().split(",")));
            List<String> fileUrls = files.stream().map(FileUpload::getUrl).collect(Collectors.toList());
            orderListVo.setFileUrls(fileUrls);
        }
        return orderListVos;
    }

    @Override
    public List<ShopOrderListVo> queryGoodsTrackList(Integer queType) {
        User user = mobileBaseService.hasLogin();
        List<ShopOrderListVo> orderListVos;
        Integer status = null;
        Integer isTimeout = null;
        if (queType == 1) {
            //待发货
            status = 2;
        } else {
            isTimeout = 1;
        }
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(status, null,
                    null, null, null, null, user.getId(),
                    null, null, isTimeout);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(status, null,
                    null, null, null, user.getStoreId(), null,
                    null, null, isTimeout);
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(status, null,
                    null, null, null, null, null,
                    user.getCompanyId(), null, isTimeout);
        } else if (Objects.equals(user.getType(), UserTypeEnum.OFFER_OPERATOR.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(status, null,
                    null, null, null, null, null,
                    null, user.getId(), isTimeout);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SUM_ACCOUNT.code())) {
            orderListVos = recycleOrderMapper.queryRecycleOrderList(status, user.getRecoveryId().intValue(),
                    null, null, null, null, null,
                    null, null, isTimeout);
        } else {
            return new ArrayList<>();
        }

        for (ShopOrderListVo orderListVo : orderListVos) {
            InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(orderListVo.getInquiryOrderId());
            List<VerifyModelOption> options = verifyModelOptionMapper.selectBatchIds(Arrays.asList(inquiryOrder.getVerifyModelIds().split(",")));
            orderListVo.setSpecs(options.stream().filter(s -> s.getType() == 1).map(VerifyModelOption::getName).collect(Collectors.joining(",")));
            List<FileUpload> files = uploadMapper.selectBatchIds(Arrays.asList(inquiryOrder.getFileIds().split(",")));
            List<String> fileUrls = files.stream().map(FileUpload::getUrl).collect(Collectors.toList());
            orderListVo.setFileUrls(fileUrls);
        }
        return orderListVos;
    }

    @Override
    public AjaxResult updateRegionInfo() {
        String resStr = HttpUtils.sendGet("https://restapi.amap.com/v3/config/district?subdistrict=3&key=ab8715d50f386df6a4577dd054fb3e1d");
        JSONObject resJson = JSONObject.parseObject(resStr);
        if (Objects.equals(resJson.get("status"), "1")) {
            JSONObject countryJson = (JSONObject) resJson.getJSONArray("districts").get(0);
            JSONArray provinceJson = countryJson.getJSONArray("districts");
            for (Object o : provinceJson) {
                JSONObject province = JSONObject.from(o);
                CfgArea provinceArea = new CfgArea();
                provinceArea.setCode(province.getString("adcode"));
                provinceArea.setLevel(province.getString("level"));
                provinceArea.setName(province.getString("name"));
                provinceArea.setParentId(0L);
                cfgAreaMapper.insert(provinceArea);
                Long provinceId = provinceArea.getId();
                JSONArray cityJson = province.getJSONArray("districts");
                for (Object o1 : cityJson) {
                    JSONObject city = JSONObject.from(o1);
                    CfgArea cityArea = new CfgArea();
                    cityArea.setCode(city.getString("adcode"));
                    cityArea.setLevel(city.getString("level"));
                    cityArea.setName(city.getString("name"));
                    cityArea.setParentId(provinceId);
                    cfgAreaMapper.insert(cityArea);
                    Long cityId = cityArea.getId();
                    JSONArray districtsJson = city.getJSONArray("districts");
                    for (Object o2 : districtsJson) {
                        JSONObject districts = JSONObject.from(o2);
                        CfgArea districtsArea = new CfgArea();
                        districtsArea.setCode(districts.getString("adcode"));
                        districtsArea.setLevel(districts.getString("level"));
                        districtsArea.setName(districts.getString("name"));
                        districtsArea.setParentId(cityId);
                        cfgAreaMapper.insert(districtsArea);
                    }
                }
            }
            return AjaxResult.success();
        } else {
            return AjaxResult.error(resJson.getString("info"));
        }
    }

    @Override
    public AjaxResult queryAreaListByType(String level) {
        LambdaQueryWrapper<CfgArea> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CfgArea::getLevel, level);
        return AjaxResult.success(cfgAreaMapper.selectVoList(wrapper));
    }

}
